package com.danielececi.database;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;

import com.danielececi.constants.IConstants;
import com.danielececi.model.Categoria;
import com.danielececi.model.Spesa;
import com.danielececi.utils.Utility;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper {

	//==== Statements creazione tabelle ====

	// Spese
	private static final String CREATE_TABLE_SPESE = "CREATE TABLE " + IConstants.TABLE_SPESE + "(" + 
													 IConstants.KEY_ID + " INTEGER PRIMARY KEY," + 
													 IConstants.KEY_IMPORTO	+ " FLOAT," + 
													 IConstants.KEY_DATA + " DATETIME," + 
													 IConstants.KEY_CATEGORIA_APPARTENENZA + " TEXT," + 
													 IConstants.KEY_NOTE +" TEXT)";
	// Categorie
	private static final String CREATE_TABLE_CATEGORIE = "CREATE TABLE " + IConstants.TABLE_CATEGORIE + "(" + 
														 IConstants.KEY_ID + " INTEGER PRIMARY KEY," + 
														 IConstants.KEY_NOME_CATEGORIA + " TEXT)";
	
	public DatabaseHelper(Context context) {
        super(context, IConstants.DATABASE_NAME, null, IConstants.DATABASE_VERSION);
    }
	
	 @Override
	 public void onCreate(SQLiteDatabase db) {

		 // Creo le tabelle richieste
		 db.execSQL(CREATE_TABLE_SPESE);
		 db.execSQL(CREATE_TABLE_CATEGORIE);
	 }

	 @Override
	 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		 // Sull'Upgrade faccio drop delle vecchie tabelle
		 db.execSQL("DROP TABLE IF EXISTS " + CREATE_TABLE_SPESE);
		 db.execSQL("DROP TABLE IF EXISTS " + CREATE_TABLE_CATEGORIE);

		 // Creo nuove tabelle
		 onCreate(db);
	 }
	 
	 public void clearDB() {
		 SQLiteDatabase db = this.getWritableDatabase();
		 // Cancello le table
		 db.execSQL("DROP TABLE IF EXISTS " + CREATE_TABLE_SPESE);
		 db.execSQL("DROP TABLE IF EXISTS " + CREATE_TABLE_CATEGORIE);
	 }
	 
	 /**
	  * Chiude la connessione al DB
	  */
	 public void closeDB() {
		 SQLiteDatabase db = this.getReadableDatabase();
		 if (db != null && db.isOpen()){
			 db.close();
		 }
	 }
	 //==== SPESE ====
	 
	 /**
	  * Crea un oggetto di tipo Spesa nella relativa Table
	  * @param spesa
	  * @return l'id della nuova spesa creata
	  */
	 public long creaSpesa(Spesa spesa) {
	     SQLiteDatabase db = this.getWritableDatabase();
	  
	     ContentValues values = new ContentValues();
	     values.put(IConstants.KEY_IMPORTO, spesa.getImporto());
	     String data = Utility.dateToString(spesa.getData(), IConstants.FORMATO_DATA_SPESE);
	     values.put(IConstants.KEY_DATA, data);
	     values.put(IConstants.KEY_CATEGORIA_APPARTENENZA, spesa.getCategoriaAppartenenza());
	     values.put(IConstants.KEY_NOTE, spesa.getNote());
	  
	     // insert row
	     long idNuovaSpesa = db.insert(IConstants.TABLE_SPESE, null, values);
	  	  
	     return idNuovaSpesa;
	 }
	 
	 /**
	  * Aggiorna una Spesa con i valori passati come argomento
	  * @param spesa
	  * @return
	  */
	 public int updateSpesa(Spesa spesa) {
	     SQLiteDatabase db = this.getWritableDatabase();
	  
	     ContentValues values = new ContentValues();
	     values.put(IConstants.KEY_IMPORTO, spesa.getImporto());
	     String data = Utility.dateToString(spesa.getData(), IConstants.FORMATO_DATA_SPESE);
	     values.put(IConstants.KEY_DATA, data);
	     values.put(IConstants.KEY_CATEGORIA_APPARTENENZA, spesa.getCategoriaAppartenenza());
	     values.put(IConstants.KEY_NOTE, spesa.getNote());
	  
	     // updating row
	     return db.update(IConstants.TABLE_SPESE, values, IConstants.KEY_ID + " = ?", new String[] { String.valueOf(spesa.getId()) });
	 }
	 
	 /**
	  * Cancella la Spesa identificata dall'ID passato come argomento
	  * @param idSpesa
	  */
	 public void deleteSpesa(long idSpesa) {
	     SQLiteDatabase db = this.getWritableDatabase();
	     db.delete(IConstants.TABLE_SPESE, IConstants.KEY_ID + " = ?",
	             new String[] { String.valueOf(idSpesa) });
	 }
	 
	 /**
	  * Restituisce la Spesa identificata da idSpesa
	  * @param idSpesa
	  * @return la Spesa desiderata
	  * @throws ParseException
	  */
	 public Spesa getSpesaByID(long idSpesa) throws ParseException {
		 SQLiteDatabase db = this.getReadableDatabase();

		 String selectQuery = "SELECT * FROM " + IConstants.TABLE_SPESE + " WHERE "
				 + IConstants.KEY_ID + " = " + idSpesa;

		 Cursor c = db.rawQuery(selectQuery, null);

		 if (c != null){
			 c.moveToFirst();
		 }

		 Spesa spesa= new Spesa();
		 spesa.setId(c.getInt(c.getColumnIndex(IConstants.KEY_ID)));
		 spesa.setImporto(c.getDouble(c.getColumnIndex(IConstants.KEY_IMPORTO)));

		 Date data = Utility.stringToDate(c.getString(c.getColumnIndex(IConstants.KEY_DATA)), IConstants.FORMATO_DATA_SPESE);
		 spesa.setData(data);

		 spesa.setCategoriaAppartenenza(c.getString(c.getColumnIndex(IConstants.KEY_CATEGORIA_APPARTENENZA)));
		 spesa.setNote(c.getString(c.getColumnIndex(IConstants.KEY_NOTE)));

		 return spesa;
	 }
	 
	 /**
	  * Restituisce un ArrayList contenente tutte le Spese
	  * @return
	  * @throws ParseException
	  */
	 public ArrayList<Spesa> getListaSpese() throws ParseException {
		 ArrayList<Spesa> listaSpese = new ArrayList<Spesa>();
		 
		 String selectQuery = "SELECT * FROM " + IConstants.TABLE_SPESE;

		 SQLiteDatabase db = this.getReadableDatabase();
		 Cursor c = db.rawQuery(selectQuery, null);
		 
		 // Ciclo sul cursore delle spese
		 if (c.moveToFirst()) {
			 do {
				 Spesa spesa = new Spesa();
				 spesa.setId(c.getInt((c.getColumnIndex(IConstants.KEY_ID))));
				 spesa.setImporto(c.getDouble(c.getColumnIndex(IConstants.KEY_IMPORTO)));
				 Date data = Utility.stringToDate(c.getString(c.getColumnIndex(IConstants.KEY_DATA)), IConstants.FORMATO_DATA_SPESE);
				 spesa.setData(data);
				 spesa.setCategoriaAppartenenza(c.getString(c.getColumnIndex(IConstants.KEY_CATEGORIA_APPARTENENZA)));
				 spesa.setNote(c.getString(c.getColumnIndex(IConstants.KEY_NOTE)));				 
				 
				 // Aggiungo la spesa alla lista
				 listaSpese.add(spesa);
			 } while (c.moveToNext());
		 }

		 return listaSpese;
	 }
	 
	 //==== CATEGORIA ====
	 
	 /**
	  * Crea un oggetto di tipo Categoria nella relativa Table
	  * @param categoria
	  * @return l'id della nuova categoria creata
	  */
	 public long creaCategoria(Categoria categoria) {
	     SQLiteDatabase db = this.getWritableDatabase();
	  
	     ContentValues values = new ContentValues();
	     values.put(IConstants.KEY_ID, categoria.getId());
	     values.put(IConstants.KEY_NOME_CATEGORIA, categoria.getNomeCategoria());
	  
	     // insert row
	     long idNuovaCategoria = db.insert(IConstants.TABLE_CATEGORIE, null, values);
	  	  
	     return idNuovaCategoria;
	 }
	 
	 /**
	  * Aggiorna una Categoria con i valori passati come argomento
	  * @param categoria
	  * @return
	  */
	 public int updateCategoria(Categoria categoria) {
	     SQLiteDatabase db = this.getWritableDatabase();
	  
	     ContentValues values = new ContentValues();
	     values.put(IConstants.KEY_ID, categoria.getId());
	     values.put(IConstants.KEY_NOME_CATEGORIA, categoria.getNomeCategoria());
	  
	     // updating row
	     return db.update(IConstants.TABLE_CATEGORIE, values, IConstants.KEY_ID + " = ?", new String[] { String.valueOf(categoria.getId()) });
	 }
	 
	 /**
	  * Cancella la Categoria identificata dall'ID passato come argomento
	  * @param idCategoria
	  */
	 public void deleteCategoria(long idCategoria) {
	     SQLiteDatabase db = this.getWritableDatabase();
	     db.delete(IConstants.TABLE_SPESE, IConstants.KEY_ID + " = ?",
	             new String[] { String.valueOf(idCategoria) });
	 }
	 
	 /**
	  * Restituisce la Categoria identificata da idCategoria
	  * @param idCategoria
	  * @return la Categoria desiderata
	  * @throws ParseException
	  */
	 public Categoria getCategoriaByID(long idCategoria) throws ParseException {
		 SQLiteDatabase db = this.getReadableDatabase();

		 String selectQuery = "SELECT * FROM " + IConstants.TABLE_CATEGORIE + " WHERE "
				 + IConstants.KEY_ID + " = " + idCategoria;

		 Cursor c = db.rawQuery(selectQuery, null);

		 if (c != null){
			 c.moveToFirst();
		 }

		 int id = c.getInt((c.getColumnIndex(IConstants.KEY_ID)));
		 String nomeCategoria = c.getString((c.getColumnIndex(IConstants.KEY_NOME_CATEGORIA)));
		 Categoria categoria = new Categoria(id, nomeCategoria);

		 return categoria;
	 }
	 
	 /**
	  * Restituisce un ArrayList contenente tutte le Categorie
	  * @return
	  * @throws ParseException
	  */
	 public ArrayList<Categoria> getListaCategorie() throws ParseException {
		 ArrayList<Categoria> listaCategorie = new ArrayList<Categoria>();

		 String selectQuery = "SELECT * FROM " + IConstants.TABLE_CATEGORIE;
		 
		 SQLiteDatabase db = this.getReadableDatabase();
		 Cursor c = db.rawQuery(selectQuery, null);

		 // Ciclo sul cursore delle categorie
		 if (c.moveToFirst()){
			 do {
				 int id = c.getInt((c.getColumnIndex(IConstants.KEY_ID)));
				 String nomeCategoria = c.getString((c.getColumnIndex(IConstants.KEY_NOME_CATEGORIA)));
				 Categoria categoria = new Categoria(id, nomeCategoria);

				 // Aggiungo la spesa alla lista
				 listaCategorie.add(categoria);
			 } while (c.moveToNext());
		 }

		 return listaCategorie;
	 }
}